<!DOCTYPE html>
<html lang="en">

<head>
    <meta charmap="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>柱状图堆叠label展示总和</title>
    <style>
        #chart {
            position: absolute;
            left: 500px;
            top: 100px;
            width: 500px;
            height: 500px;
        }
    </style>
</head>

<body>
    <div id="chart"></div>
    <script crossorigin="anonymous"
        integrity="sha512-CNXD81ugRg68yNQQ9TSlZb/pLzbJ5Xo+QRQhIKxW7U3wwYOTcb9O0Q+3yWiWvwBElV/z7oo0hlqOqxPyMbZ8zQ=="
        src="https://lib.baomitu.com/echarts/5.3.3/echarts.common.js"></script>
    <script>

        const defaultShowLabel = true // 默认是否展示label
        const globalChart = {
            instance: null,
            option: null,
            series: [],
            selected: {
                A: true,
                B: true,
                C: true
            }
        }

        const myChart = echarts.init(document.getElementById('chart'))
        const option = {
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                },
            },
            legend: { show: true },
            grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
            xAxis: {
                type: 'category',
                splitLine: { show: false },
                data: ['小红', '小明', '小黑']
            },
            yAxis: { type: 'value' },
            series: [
                {
                    name: 'A',
                    type: 'bar',
                    stack: '堆叠',
                    barWidth: 50,
                    barMinHeight: 5,
                    label: {
                        show: defaultShowLabel,
                        position: 'top',
                        formatter: function (param) {
                            if (
                                (!globalChart.series[2].data[param.dataIndex].value || !globalChart.selected['C'])
                                && (!globalChart.series[1].data[param.dataIndex].value || !globalChart.selected['B'])
                            ) {
                                return param.data.sum
                            } else {
                                return ''
                            }
                        }
                    },
                    data: [
                        { value: 1 },
                        { value: 2 },
                        { value: 3 },
                        { value: 4 },
                        { value: 5 }
                    ]
                },
                {
                    name: 'B',
                    type: 'bar',
                    stack: '堆叠',
                    barWidth: 50,
                    barMinHeight: 5,
                    label: {
                        show: defaultShowLabel,
                        position: 'top',
                        formatter: function (param) {
                            if (
                                !globalChart.series[2].data[param.dataIndex].value
                                || !globalChart.selected['C']
                            ) {
                                return param.data.sum
                            } else {
                                return ''
                            }
                        }
                    },
                    data: [
                        { value: 1 },
                        { value: null },
                        { value: 5 },
                        { value: 7 },
                        { value: 9 }
                    ]
                },
                {
                    name: 'C',
                    type: 'bar',
                    stack: '堆叠',
                    barWidth: 50,
                    barMinHeight: 5,
                    label: {
                        show: defaultShowLabel,
                        position: 'top',
                        formatter: function (param) {
                            if (
                                globalChart.series[2].data[param.dataIndex].value
                                && globalChart.selected['C']
                            ) {
                                return param.data.sum
                            } else {
                                return ''
                            }
                        }
                    },
                    data: [
                        { value: 1 },
                        { value: 3 },
                        { value: null },
                        { value: 6 },
                        { value: 8 }
                    ]
                }]
        };
        globalChart.instance = myChart
        globalChart.option = option
        globalChart.series = option.series

        calcLabelSum()
        judgeLabelShowOrHide()
        myChart.setOption(option)

        myChart.off('legendselectchanged');
        myChart.on('legendselectchanged', function (param) {
            globalChart.selected = param.selected
            calcLabelSum()
            judgeLabelShowOrHide()
            myChart.setOption(globalChart.option);
        })

        function calcLabelSum () {
            const { series, selected } = globalChart
            const selectedArr = Object.values(selected)
            const filterSeries = []
            selectedArr.forEach((item, index) => { if (item) filterSeries.push(series[index]) })
            const sumArr = filterSeries.reduce(
                (total, { data }) => data.map((item, index) => total[index] + (item.value || 0))
                , Array(filterSeries[0]?.data.length).fill(0)
            )
            series.forEach((series, seriesIndex) => {
                series.data.forEach((item, index) => {
                    item.sum = sumArr[index]
                })
            })
        }

        function judgeLabelShowOrHide () {
            const { series, selected } = globalChart
            const selectedArr = Object.values(selected)
            series.forEach((value, index) => {
                if (defaultShowLabel) {
                    value.label.show = selectedArr[index]
                } else {
                    value.label.show = false
                }
            })
        }

    </script>
</body>

</html>